package com.mcp.converter.domain.rule.compatibility.function;

import com.mcp.converter.domain.checker.IncompatibilityDetail;
import com.mcp.converter.shared.response.sql.SQLElement;
import com.mcp.converter.domain.rule.compatibility.AbstractFunctionRule;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 系统函数兼容性规则
 * OceanBase中系统函数的实现与Oracle有差异
 * @author zengxiong
 */
public class SystemFunctionRule extends AbstractFunctionRule {

    private static final String RULE_ID = "FN013";
    private static final String RULE_NAME = "系统函数实现差异";
    private static final String RULE_DESCRIPTION = "OceanBase中系统函数的实现与Oracle存在差异";

    private static final Set<String> INCOMPATIBLE_SYSTEM_FUNCTIONS = new HashSet<>(Arrays.asList(
        "ORA_ROWSCN", "NLS_CHARSET_NAME", "NLS_CHARSET_ID"
    ));

    public SystemFunctionRule() {
        super(RULE_ID, RULE_NAME, RULE_DESCRIPTION);
        setIncompatibilityDetail(
            "OceanBase中以下系统函数与Oracle存在差异或不支持：\n" +
            "1. ORA_ROWSCN：\n" +
            "   - 行级SCN实现可能不同\n" +
            "   - 返回值格式可能有差异\n" +
            "2. NLS_CHARSET_NAME：\n" +
            "   - 字符集名称映射不同\n" +
            "   - 支持的字符集范围有限\n" +
            "3. NLS_CHARSET_ID：\n" +
            "   - 字符集ID映射不同\n" +
            "   - ID编号体系可能不兼容",
            "可能导致：\n" +
            "1. 行版本控制功能异常\n" +
            "2. 字符集转换问题\n" +
            "3. 国际化功能受限",
            "建议：\n" +
            "1. ORA_ROWSCN：\n" +
            "   - 使用时间戳或版本号替代\n" +
            "   - 在应用层实现行版本控制\n" +
            "2. NLS函数：\n" +
            "   - 统一使用UTF-8字符集\n" +
            "   - 在应用层处理字符集转换\n" +
            "3. 通用建议：\n" +
            "   - 减少对Oracle特有系统函数的依赖\n" +
            "   - 建立完整的测试用例",
            IncompatibilityDetail.Severity.MEDIUM
        );
    }

    @Override
    public boolean matches(Object target) {
        if (target instanceof SQLElement) {
            SQLElement element = (SQLElement) target;
            if (isFunctionElement(element)) {
                String functionName = element.getName().toUpperCase();
                return INCOMPATIBLE_SYSTEM_FUNCTIONS.contains(functionName);
            }
        }
        return false;
    }
    
    @Override
    public Set<String> getIncompatibleFunctions() {
        return new HashSet<>(INCOMPATIBLE_SYSTEM_FUNCTIONS);
    }
}
